Skip to content

gh-107557: Setup abstract interpretation#107847

Merged
Fidget-Spinner merged 54 commits intopython:mainfrom
Fidget-Spinner:partition_algo
Aug 15, 2023
Merged

gh-107557: Setup abstract interpretation#107847
Fidget-Spinner merged 54 commits intopython:mainfrom
Fidget-Spinner:partition_algo

Conversation

@Fidget-Spinner
Copy link
Member

@Fidget-Spinner Fidget-Spinner commented Aug 10, 2023

This is joint work by @JuliaPoo and me, supported by the NUS TEST Lab.

This implements a subset of partial evaluation (specifically, constant propagation), using a technique described for our type propagation in our Tier 2 interpreter report and abstract interpretation over uops.

The main goal of upstreaming this PR is to set up the infrastructure for optimization passes of CPython uops. With constant propagation, turning global loads or attribute loads to constants at the region formation phase will open up further optimizations in subsequent passes. This PR also makes CPython uops ready for type propagation, thus allowing wide-scale typed operations.

Features:

  • An automatically generated abstract interpreter from the interpreter DSL.
  • Abstract interpretation of uops.
  • Partitioning of values on the stack and locals into static/dynamic using the concept of "partitions of nodes".
  • Introduces the concept of "pure" operations, and what can be ascertained about them.
  • Constant propagation purely via abstract interpretation of bytecode, with no requirement for SSA or AST.
  • An optimization pass to remove redundant SAVE_IPs after partial evaluation.
  • Jump target/instruction numbering, which allows us to freely relocate jump targets/instructions, as a final pass will fix them up.

Example:
We have the following test case.

        def testfunc(loops):
            num = 0
            while num < loops:
                x = 0
                y = 1
                z = 2
                a = x + y + z + x + y + z + x + y + z
                num += 1
            return a

This is now essentially simplified down to:

        def testfunc(loops):
            num = 0
            while num < loops:
                x = 0
                y = 1
                z = 2
                a = 9
                num += 1
            return a

Which roughly halves the trace length.

TODO:

  • Use lltrace convention commonly seen in rest of the uops codebase.
  • Cleanup.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

interpreter-core (Objects, Python, Grammar, and Parser dirs)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants